package model

import (
	ryrpc "admin/rpc"
	"common/helper"
	"common/userHelp"
	"errors"
	"fmt"
	g "github.com/doug-martin/goqu/v9"
	"github.com/valyala/fasthttp"
	"strconv"
)

type TblMemberAdjust struct {
	Id           string  `json:"id" cbor:"id" db:"id"`
	Uid          string  `json:"uid" cbor:"uid" db:"uid"`
	Username     string  `json:"username" cbor:"username" db:"username"`
	Amount       float64 `json:"amount" cbor:"amount" db:"amount"`
	WagerTimes   int     `json:"wager_times" cbor:"wager_times" db:"wager_times"`
	AdjustMode   int     `json:"adjust_mode" cbor:"adjust_mode" db:"adjust_mode"`
	ApplyRemark  string  `json:"apply_remark" cbor:"apply_remark" db:"apply_remark"`
	ReviewRemark string  `json:"review_remark" cbor:"review_remark" db:"review_remark"`
	State        int     `json:"state" cbor:"state" db:"state"`
	ApplyAt      int64   `json:"apply_at" cbor:"apply_at" db:"apply_at"`
	ApplyUid     string  `json:"apply_uid" cbor:"apply_uid" db:"apply_uid"`
	ApplyName    string  `json:"apply_name" cbor:"apply_name" db:"apply_name"`
	ReviewAt     int64   `json:"review_at" cbor:"review_at" db:"review_at"`
	ReviewUid    string  `json:"review_uid" cbor:"review_uid" db:"review_uid"`
	ReviewName   string  `json:"review_name" cbor:"review_name" db:"review_name"`
	Tester       int     `json:"tester" cbor:"tester" db:"tester"`
}

type TblMemberAdjustData struct {
	Id           string  `json:"id" cbor:"id" db:"id"`
	Uid          string  `json:"uid" cbor:"uid" db:"uid"`
	Username     string  `json:"username" cbor:"username" db:"username"`
	Amount       float64 `json:"amount" cbor:"amount" db:"amount"`
	WagerTimes   int     `json:"wager_times" cbor:"wager_times" db:"wager_times"`
	AdjustMode   int     `json:"adjust_mode" cbor:"adjust_mode" db:"adjust_mode"`
	ApplyRemark  string  `json:"apply_remark" cbor:"apply_remark" db:"apply_remark"`
	ReviewRemark string  `json:"review_remark" cbor:"review_remark" db:"review_remark"`
	State        int     `json:"state" cbor:"state" db:"state"`
	ApplyAt      int64   `json:"apply_at" cbor:"apply_at" db:"apply_at"`
	ApplyUid     string  `json:"apply_uid" cbor:"apply_uid" db:"apply_uid"`
	ApplyName    string  `json:"apply_name" cbor:"apply_name" db:"apply_name"`
	ReviewAt     int64   `json:"review_at" cbor:"review_at" db:"review_at"`
	ReviewUid    string  `json:"review_uid" cbor:"review_uid" db:"review_uid"`
	ReviewName   string  `json:"review_name" cbor:"review_name" db:"review_name"`
	Tester       int     `json:"tester" cbor:"tester" db:"tester"`
	OperatorId   string  `json:"operator_id" db:"operator_id"`
	OperatorName string  `json:"operator_name" db:"operator_name"`
	BusinessId   string  `json:"business_id" db:"business_id"`
	BusinessName string  `json:"business_name" db:"business_name"`
}

type AdjustData struct {
	T int                   `cbor:"t" json:"total"`
	D []TblMemberAdjustData `cbor:"d" json:"d"`
}

// AdjustList 账户调整列表
func AdjustList(param Adjustparam, ctx *fasthttp.RequestCtx) (AdjustData, error) {

	data := AdjustData{}

	where := "1=1"
	oderBy := "a.apply_at"
	oderType := "desc"

	if param.Uid != "" {
		where += " and a.uid=" + param.Uid
	}
	if param.State != "" {
		where += " and a.state=" + param.State
	}
	if param.AdjustMode != "" {
		where += " and a.adjust_mode=" + param.AdjustMode
	}
	if param.OperatorId != "" {
		where += " and a.apply_uid=" + param.OperatorId
	}
	if param.BusinessId != "" {
		where += " and a.apply_uid=" + param.BusinessId
	}
	if param.StartTime != "" {
		StartTime, _ := helper.TimeToLoc(param.StartTime, loc)
		where += " and a.apply_at>='" + strconv.FormatInt(StartTime, 10) + "'"
	}
	if param.EndTime != "" {
		EndTime, _ := helper.TimeToLoc(param.EndTime, loc)
		where += " and a.apply_at<='" + strconv.FormatInt(EndTime, 10) + "'"
	}
	loginUser := GetLoginUser(ctx)
	if loginUser.Operator != "" {
		where += " and a.apply_name like 'operator:" + loginUser.Operator + "%'"
	} else if loginUser.Businsess != "" {
		where += " and a.apply_name like '%-business:" + loginUser.Businsess + "'"
	} else {
		if param.IsOperator == 1 {
			where += " and a.apply_name like 'operator:" + loginUser.Operator + "%'"
		} else {
			where += " and a.apply_name not like 'operator:" + loginUser.Operator + "%'"
		}
	}
	if param.OderBY != "" {
		oderBy = param.OderBY
	}
	if param.OderType != "" {
		oderType = param.OderType
	}

	table := "tbl_member_adjust"
	order := oderBy + " " + oderType
	join := " left join tbl_member_base as b on b.uid=a.uid"          //玩家表
	join += " left join tbl_operator_info as c on c.id=b.operator_id" //渠道表
	join += " left join tbl_business_info as d on d.id=b.business_id" //业务员表

	offset := (param.Page - 1) * param.PageSize
	if param.Page >= 1 {
		count := "select count(1) from " + table + " as a " + join + " where " + where

		err := meta.MerchantDB.Get(&data.T, count)
		if err != nil {

			return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), count), "数据库错误")
		}

		if data.T == 0 {
			return data, nil
		}
	}
	field := "a.*" +
		",ifnull(c.id,'') operator_id" +
		",ifnull(c.operator_name,'') operator_name" +
		",ifnull(d.id,'') business_id" +
		",ifnull(d.account_name,'') as business_name"

	query := "select " + field + " from " + table + " as a " + join + " where " + where + " order by " + order + " limit " + strconv.Itoa(param.PageSize) + " offset " + strconv.Itoa(offset)

	err := meta.MerchantDB.Select(&data.D, query)
	if err != nil {
		return data, pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
	}
	businessList, _ := GetBusinessMap()
	operatorList, _ := GetOperatorMap()
	for key, value := range data.D {
		len := len((data.D)[key].ApplyUid)
		if len == 5 {
			(data.D)[key].ApplyName = "总后台:" + value.ApplyName
		}
		if len == 6 {
			(data.D)[key].ApplyName = "渠道:" + operatorList[value.ApplyUid]
		}
		if len == 7 {
			(data.D)[key].ApplyName = "业务员:" + businessList[value.ApplyUid]
		}
	}
	return data, nil
}

func AdjustInsert(data TblMemberAdjust, userinfo ryrpc.TblMemberBase, loginuser string) error {
	//额度判断

	operatorQuoteData, _ := GetQuoteDataByOperatorId(userinfo.OperatorId)
	//上分
	if data.AdjustMode == 1 {
		if userinfo.Tester == 1 {
			if (operatorQuoteData.BalanceUsed + data.Amount) > operatorQuoteData.BalanceQuota {
				if loginuser != "admin" {
					return errors.New("额度不足")
				}

			}
			operatorQuoteData.BalanceUsed += data.Amount
		}
		if userinfo.Tester == 2 {
			if (operatorQuoteData.TestMemberUsed + data.Amount) > operatorQuoteData.TestMemberQuota {
				if loginuser != "admin" {
					return errors.New("额度不足")
				}
			}
			operatorQuoteData.TestMemberUsed += data.Amount
		}
	}

	tx, err := meta.MerchantDB.Begin()
	if data.AdjustMode == 1 {
		query, _, _ := dialect.Insert("tbl_member_adjust").Rows(&data).ToSQL()
		_, err = meta.MerchantDB.Exec(query)
		if err != nil {
			tx.Rollback()
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
	} else if data.AdjustMode == 2 { //下分扣钱
		ret, err := UpdateBalance(data.Uid, -data.Amount, helper.TransactionDownPoint, data.Id)
		if ret == false {
			tx.Rollback()
			return err
		}
		query, _, _ := dialect.Insert("tbl_member_adjust").Rows(&data).ToSQL()
		_, err = meta.MerchantDB.Exec(query)
		if err != nil {
			tx.Rollback()
			return pushLog(fmt.Errorf("%s,[%s]", err.Error(), query), "数据库错误")
		}
	}
	if loginuser != "admin" {
		err = UpdateQuote(operatorQuoteData)
		if err != nil {
			tx.Rollback()
			return err
		}
	}

	tx.Commit()
	return nil
}

// AdjustReview 账户调整-审核
func AdjustReview(state string, record g.Record) error {
	tx, err := meta.MerchantDB.Begin()

	data := TblMemberAdjust{}
	query, _, _ := dialect.From("tbl_member_adjust").
		Select(colsMemberAdjust...).Where(g.Ex{"id": record["id"]}).Limit(1).ToSQL()
	query += " for update"

	err = meta.MerchantDB.Get(&data, query)
	if err != nil {
		tx.Rollback()
		return errors.New("数据库错误")
	}

	// 只有审核中状态的才能操作
	if fmt.Sprintf(`%d`, data.State) != AdjustReviewing {
		tx.Rollback()
		return errors.New("状态错误")
	}
	record["apply_remark"] = data.ApplyRemark

	r := g.Record{
		"state":         record["state"], //审核状态:1=审核中,2=审核通过,3=审核未通过
		"review_remark": record["review_remark"],
		"review_at":     record["review_at"],
		"review_uid":    record["review_uid"],
		"review_name":   record["review_name"],
	}
	// 更新调整记录状态
	query, _, _ = dialect.Update("tbl_member_adjust").Set(r).Where(g.Ex{"id": record["id"]}).ToSQL()

	_, err = tx.Exec(query)
	if err != nil {
		_ = tx.Rollback()
		return pushLog(err, "数据库错误")
	}
	if state == AdjustReviewReject {
		if data.AdjustMode == 1 { //上分
			//退回额度
			userinfo, _ := MemberFindByUid(data.Uid)
			OperatorInfo, _ := GetOperatorInfoById(userinfo.OperatorId)
			operatorQuoteData, _ := GetQuoteDataByOperatorId(OperatorInfo.Id)
			if data.Tester == 1 {
				operatorQuoteData.BalanceUsed -= data.Amount
			}
			if data.Tester == 2 {
				if (operatorQuoteData.TestMemberUsed + data.Amount) > operatorQuoteData.TestMemberQuota {
					return errors.New("额度不足")
				}
				operatorQuoteData.TestMemberUsed -= data.Amount
			}
			err = UpdateQuote(operatorQuoteData)
			if err != nil {
				tx.Rollback()
				return err
			}
		}

		if data.AdjustMode == 2 { //下分
			ret, err := UpdateBalance(data.Uid, data.Amount, helper.TransactionDownPointBack, data.Id)
			if ret == false {
				tx.Rollback()
				return pushLog(err, "数据库错误")
			}
		}
	}
	if state == AdjustReviewPass {
		if data.AdjustMode == 1 { //上分
			ret, err := UpdateBalance(data.Uid, data.Amount, helper.TransactionUpPoint, data.Id)
			if ret == false {
				tx.Rollback()
				return pushLog(err, "数据库错误")
			}

			wager_times := float64(data.WagerTimes)
			userHelp.AddUserWageManual(data.Uid, data.Amount, wager_times)
		}

		if data.AdjustMode == 2 { //下分

		}
	}

	tx.Commit()
	return nil
}

func GetAdjustOrderIds(where string) []string {
	data := []string{}
	query := "select id from tbl_member_adjust where " + where
	meta.MerchantDB.Select(&data, query)
	return data
}

func AdjustLock(id string) error {

	key := fmt.Sprintf("adjust:order:%s", id)
	err := Lock(key)
	if err != nil {
		return err
	}

	return nil
}

func AdjustUnLock(id string) {
	Unlock(fmt.Sprintf("adjust:order:%s", id))
}
